package com.wolfcode.appointment.service.impl;

import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;

import com.wolfcode.appointment.domain.BusStatement;
import com.wolfcode.appointment.domain.vo.BusStatementAndStatementItemsVo;
import com.wolfcode.appointment.domain.vo.BusStatementWithItemVo;
import com.wolfcode.appointment.enums.StatementEnum;
import com.wolfcode.appointment.mapper.BusStatementMapper;
import com.wolfcode.appointment.service.IBusStatementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wolfcode.appointment.mapper.BusStatementItemMapper;
import com.wolfcode.appointment.domain.BusStatementItem;
import com.wolfcode.appointment.service.IBusStatementItemService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

/**
 * 结算单明细Service业务层处理
 * 
 * @author wolfcode
 * @date 2022-11-25
 */
@Service
public class BusStatementItemServiceImpl implements IBusStatementItemService 
{
    @Autowired
    private BusStatementItemMapper busStatementItemMapper;
    @Autowired
    private IBusStatementService busStatementService;
    @Autowired
    private BusStatementMapper busStatementMapper;
    /**
     * 查询结算单明细
     * 
     * @param id 结算单明细主键
     * @return 结算单明细
     */
    @Override
    public BusStatementItem selectBusStatementItemById(Long id)
    {
        return busStatementItemMapper.selectBusStatementItemById(id);
    }

    /**
     * 查询结算单明细列表
     * 
     * @param busStatementItem 结算单明细
     * @return 结算单明细
     */
    @Override
    public List<BusStatementItem> selectBusStatementItemList(BusStatementItem busStatementItem)
    {
        return busStatementItemMapper.selectBusStatementItemList(busStatementItem);
    }

    /**
     * 新增结算单明细
     * 
     * @param busStatementItem 结算单明细
     * @return 结果
     */
    @Override
    public int insertBusStatementItem(BusStatementItem busStatementItem)
    {
        return busStatementItemMapper.insertBusStatementItem(busStatementItem);
    }

    /**
     * 修改结算单明细
     * 
     * @param busStatementItem 结算单明细
     * @return 结果
     */
    @Override
    public int updateBusStatementItem(BusStatementItem busStatementItem)
    {
        return busStatementItemMapper.updateBusStatementItem(busStatementItem);
    }

    /**
     * 批量删除结算单明细
     * 
     * @param ids 需要删除的结算单明细主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementItemByIds(Long[] ids)
    {
        return busStatementItemMapper.deleteBusStatementItemByIds(ids);
    }

    /**
     * 删除结算单明细信息
     * 
     * @param id 结算单明细主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementItemById(Long id)
    {
        return busStatementItemMapper.deleteBusStatementItemById(id);
    }

    /**
     * 保存结算单明细
     * @param busStatementAndStatementItemsVo
     * @return
     */
    @Override
    @Transactional
    public void save(BusStatementAndStatementItemsVo busStatementAndStatementItemsVo) {
        //1关卡（ 数据合法性）
        Assert.notNull(busStatementAndStatementItemsVo,"非法参数");
        //校验集合是否未空
        List<BusStatementItem> busStatementItems = busStatementAndStatementItemsVo.getBusStatementItems();
        Assert.notEmpty(busStatementItems,"结算单明细表不能未空");
        //结算单明细表不能存在空元素
        Assert.noNullElements(busStatementItems,"结算单明细表存在空明细");
        BusStatementWithItemVo busStatementWithItemVo = busStatementAndStatementItemsVo
                .getBusStatementWithItemVo();
        Assert.notNull(busStatementWithItemVo,"结算单不能为空");

        //2 关卡（保存一张结算单，对应多个明细）
        Assert.state(checkUniqueStatement(busStatementItems),"只能保存一张结算单");
        //3关卡（ 状态校验）已支付不用保存，消费中才可以保存
        // 数据库结算单查询，需要结算单id
        Long statementId = busStatementItems.get(0).getStatementId();
        BusStatement busStatement = busStatementService.selectBusStatementById(statementId);
        Assert.state(busStatement.getStatus()== StatementEnum.COSTING.ordinal()
                ,"消费中才可以保存");
        //4 落库
        //新增结算单明细 | 更新结算单明细
        //statementId存在明细，我先删除
        List<BusStatementItem> statementItems = busStatementItemMapper
                .selectBusStatementItemByStatementId(statementId);
        if(!CollectionUtils.isEmpty(statementItems)){
            busStatementItemMapper.deleteBusStatementItemByStatementId(statementId);
        }
        BigDecimal totalAmount=new BigDecimal(0);
        long totalQuantity=0;
        for (BusStatementItem busStatementItem : busStatementItems) {
            busStatementItemMapper.insertBusStatementItem(busStatementItem);
            //总价格: 单价*数量
            totalAmount=totalAmount.add(busStatementItem.getItemPrice()
                    .multiply(new BigDecimal(busStatementItem.getItemQuantity()+"")));
            // 计算服务总数量
            totalQuantity+= busStatementItem.getItemQuantity();
        }
        // 计算出来之后TotalAmount，才去判断
        // 校验优惠价格不能大于总消费
        Assert.state(totalAmount
                .compareTo(busStatementWithItemVo.getDiscountAmount())>0,"优惠价格不能大于总消费");
        //更新结算单
        BusStatement updateStatement=new BusStatement();
        updateStatement.setId(statementId);
        // 总消费
        updateStatement.setTotalAmount(totalAmount);
        // 总服务项数量
        updateStatement.setTotalQuantity(new BigDecimal(totalQuantity));
        // 折扣价
        updateStatement.setDiscountAmount(busStatementWithItemVo.getDiscountAmount());
        busStatementMapper.updateBusStatement(updateStatement);
    }

    /**
     * 校验结算单明细数据的唯一性
     * @param busStatementItems
     * @return
     */
    private boolean checkUniqueStatement(List<BusStatementItem> busStatementItems) {
        HashSet set=new HashSet();
        for (BusStatementItem busStatementItem : busStatementItems) {
            //结算单id
            set.add(busStatementItem.getStatementId());
        }
        return set.size()==1;
    }


}
